package br.senac.sp.persistence;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;

public abstract class AbstractPersistenceMapper<Entity, OID> implements IMapper<Entity, OID> {

    private Map<OID, Entity> cachedObjects = new HashMap<OID, Entity> ();

    @Override
    public Entity get(OID id) {
        Entity entity = cachedObjects.get(id);
        if (entity == null) {
            entity = getObjectFromStorage(id);
            cachedObjects.put(id, entity);
        }
        return entity;
    }

    @Override
    public List<Entity> get() {
        List<Entity> entities = getObjectFromStorage();
        for (Entity entity : entities) {
            cachedObjects.put(getIdFromObject(entity), entity);
        }
        return entities;
    }

    @Override
    public void put(Entity entity) {
        if (getIdFromObject(entity) == null) {
            insertNewEntityInStorage(entity);
        } else {
            updateEntityInStorage(entity);
        }
    }

    @Override
    public void remove(Entity entity) {
        if (getIdFromObject(entity) != null) {
            cachedObjects.remove(entity);
            removeObjectFromStorage(entity);
        }

    }

    protected abstract Entity getObjectFromStorage(OID id);

    protected abstract List<Entity> getObjectFromStorage();

    protected abstract void insertNewEntityInStorage(Entity entity);

    protected abstract void updateEntityInStorage(Entity entity);

    protected abstract void removeObjectFromStorage(Entity entity);

    protected abstract OID getIdFromObject(Entity entity);
}
